package com.css.apps.base.dict.service;

import com.css.apps.base.dict.model.SDict;
import com.css.apps.base.log.model.LogConstant;
import com.css.apps.base.log.model.LogPart;
import com.css.db.memcached.MemCachedFactory;
import com.css.db.query.QueryCache;
import com.css.db.query.TransactionCache;
import com.css.util.Json;
import com.css.util.Md5Util;
import com.css.util.StringHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.*;

public class DictMan {

	private static Log log = LogFactory.getLog(DictMan.class);

	/**
	 * 根据字典名和字典项名获取对应的字典编码,查不到直接返回名称
	 * @param tableCode
	 * @param name
	 */
	public static String getDictCodeByName(String tableCode, String name) {
		try {
			String pid = new QueryDict("select a.uuid from SDict a where a.code=:code").setParameter("code",tableCode).list().get(0).toString();
			String code =new QueryDict("select a.code from SDict a where a.name =:name and a.parentId=:pid").setParameter("name",name).setParameter("pid",pid).list().get(0).toString();
			return StringHelper.isNotEmpty(code) ? code : "";
		}catch (Exception e){
			e.printStackTrace();
			return name;
		}
	}

	public static void main(String[] args) {
		System.out.println(getDictCodeByName("d_sex","男"));
	}

	/**
	 * 通过字典表名获取QueryCache对象
	 * 
	 * @author liuzhb on Jan 6, 2014 9:57:02 AM
	 */
	public static QueryCache getDictListConf(String tableName) {
		String parentId = getUuid("d_root", tableName);
		QueryCache qc = new QueryDict(" from SDict a where a.parentId = :parentId order by code")
				.setParameter("parentId", parentId);
		return qc;
	}

	/**
	 * 通过字典表名获取值为dictId的List对象，便于通过dictId查找SDict对象
	 * 
	 * @author liuzhb on Jan 6, 2014 9:59:36 AM
	 */
	public static List<String> getDictTypeId(String table) {
		List<SDict> lst = DictMan.getDictType(table);
		List<String> lstId = new ArrayList<>();
		for (SDict dt : lst)
			lstId.add(dt.getUuid());
		return lstId;
	}

	/**
	 * 通过字典表名获取值为SDict的List对象，
	 * 
	 * @author liuzhb on Jan 6, 2014 10:01:14 AM
	 */
	@SuppressWarnings("unchecked")
	public static List<SDict> getDictType(String table) {
		if (StringHelper.isEmpty(table))
			return null;
		QueryCache qc = getDictListConf(table);
		boolean isNoCache = qc.isNoCache();
		List<SDict> lstRes = qc.listCache(-1);
		if (isNoCache) {
			for (Object obj : lstRes) {
				SDict sDict = (SDict) obj;
				addItemCache(sDict);
			}
		}
		return lstRes;
	}

	public static String getDictName(String table, String dictId) {
		if (StringHelper.isEmpty(table) || StringHelper.isEmpty(dictId))
			return "";
		String uuid = getUuid(table, dictId);
		SDict dict = QueryDict.get(SDict.class, uuid);
		return dict == null ? "" : dict.getName();
	}

	public static String getDictNameByCode(String table,String code){
		if (StringHelper.isEmpty(table) || StringHelper.isEmpty(code))
			return "";
		String name = new QueryDict("select a.name from SDict a where a.tableName=:tableName and a.code=:code").setParameter("tableName",table).setParameter("code",code).setMaxResults(1).uniqueResult().toString();
		return StringHelper.isEmpty(name)? "": name;
	}

	/**
	 * 通过字典表名清理memcached中的字典缓存
	 * 
	 * @author liuzhb on Jan 6, 2014 10:02:23 AM
	 */
	public static void clearTableCache(String table) {
		QueryCache qc = getDictListConf(table);
		qc.listCacheRemove();
	}

	/**
	 * 通过字典表名、dictId获取单个字典对象
	 * 
	 * @author liuzhb on Jan 6, 2014 10:04:39 AM
	 */
	public static SDict getDictType(String table, String dictId) {
		if (StringHelper.isEmpty(table) || StringHelper.isEmpty(dictId))
			return null;
		String uuid = getUuid(table, dictId);
		return QueryDict.get(SDict.class, uuid);
	}

	/**
	 * 将字典添加到memcached缓存中
	 * 
	 * @author liuzhb on Jan 6, 2014 10:06:40 AM
	 */
	public static void addItemCache(SDict dt) {
		String key = QueryCache.getKey(QueryDict.MAPPING, dt.getClass().getName(), dt.getUuid());
		MemCachedFactory.set(key, dt);
	}

	/**
	 * 将字典从memcached缓存清除
	 * 
	 * @author liuzhb on Jan 6, 2014 10:07:07 AM
	 */
	public static void delItemCache(SDict dt) {
		String key = QueryCache.getKey(QueryDict.MAPPING, dt.getClass().toString(), dt.getUuid());
		MemCachedFactory.delete(key);
	}

	public static List<SDict> getDictList(String table, String firstVal) {
		List<SDict> dict = getDictType(table);
		List<SDict> lstRes = new ArrayList<>();
		if (StringHelper.isNotEmpty(firstVal)) {
			SDict dictType = new SDict();
			dictType.setName(firstVal);
			lstRes.add(dictType);
		}
		lstRes.addAll(dict);
		return lstRes;
	}

	/**
	 * 通过表名获取字典列表
	 * 
	 * @author liuzhb on Jan 6, 2014 10:07:28 AM
	 */
	public static List<SDict> getDictListQuery(String table) {
		return getDictList(table, "全部");
	}

	/**
	 * 通过表名获取字典列表（该方法用于下拉菜单中，在下拉菜单的第一个选项总添加“请选择”）
	 * 
	 * @author liuzhb on Jan 6, 2014 10:07:53 AM
	 */
	public static List<SDict> getDictListSel(String table) {
		return getDictList(table, "请选择");
	}

	/**
	 * 添加字典项
	 * 
	 * @author liuzhb on Jan 3, 2014 11:35:57 AM
	 */
	public static void addDict(SDict dict) {
		TransactionCache tx = null;
		try {
			tx = new QueryDict().getTransaction();
			tx.getSession().save(dict);
			tx.commit();
			LogPart lp = new LogPart();
			lp.setOpObjType(SDict.class.getName());
			lp.setOpObjId(dict.getUuid());
			lp.setRelObjType(SDict.class.getName());
			lp.setRelObjId(dict.getUuid());
			lp.setOpType(LogConstant.LOG_TYPE_ADD);
			lp.setLogLevel(LogConstant.LOG_LEVEL_COMMON);
			lp.setLogData(Json.object2json(dict));
			lp.setResult(LogConstant.RESULT_SUCCESS);
			lp.save();
			clearTableCache(dict.getTableName());
			addItemCache(dict);
		} catch (Exception ex) {
			if (tx != null)
				tx.rollback();
			log.error(ex.getMessage());
		}
	}

	/**
	 * 更新字典项
	 * 
	 * @author liuzhb on Jan 3, 2014 11:35:57 AM
	 */
	public static boolean updateDict(SDict dict) {
		try {
			SDict newDict = new SDict();
			newDict.setCode(dict.getCode());
			newDict.setName(dict.getName());
			newDict.setOrderNum(dict.getOrderNum());
			newDict.setParentId(dict.getParentId());
			newDict.setRemark(dict.getRemark());
			newDict.setTableName(dict.getTableName());
			newDict.setUuid(DictMan.getUuid(dict.getTableName(), dict.getCode()));

			// 先删除原有记录
			List<String> dictIdList = StringHelper.strToList(dict.getUuid());
			DictMan.delDict(dictIdList);
			// 添加新记录
			DictService.addDict(newDict);
			LogPart lp = new LogPart();
			lp.setOpObjType(SDict.class.getName());
			lp.setOpObjId(dict.getUuid());
			lp.setRelObjType(SDict.class.getName());
			lp.setRelObjId(dict.getUuid());
			lp.setOpType(LogConstant.LOG_TYPE_MODIFY);
			lp.setLogLevel(LogConstant.LOG_LEVEL_COMMON);
			lp.setLogData(Json.object2json(dict));
			lp.setResult(LogConstant.RESULT_SUCCESS);
			lp.save();
			clearTableCache(dict.getTableName());
			addItemCache(dict);
			return true;
		} catch (Exception ex) {
			log.error(ex.getMessage());
			return false;
		}
	}

	/**
	 * 删除多个字典项
	 * 
	 * @author liuzhb on Jan 3, 2014 1:05:29 PM
	 * @param dictIdList
	 * @return
	 */

	public static void delDict(List<String> dictIdList) {
		if (dictIdList != null && dictIdList.size() > 0) {
			Map<String, List<SDict>> dictMap = new HashMap<String, List<SDict>>();
			initDictMap(dictIdList, dictMap);
			if (dictMap != null && dictMap.size() > 0) {
				Set<String> set = dictMap.keySet();
				Iterator<String> iter = set.iterator();
				while (iter.hasNext()) {
					String parentId = iter.next();
					List<SDict> list = dictMap.get(parentId);
					if (list != null && list.size() > 0) {
						QueryCache qc = new QueryDict();
						TransactionCache tc = qc.getTransaction();
						tc.delete(list);
						tc.commit();
						for (SDict dict : list) {
							LogPart lp = new LogPart();
							lp.setOpObjType(SDict.class.getName());
							lp.setOpObjId(dict.getUuid());
							lp.setRelObjType(SDict.class.getName());
							lp.setRelObjId(dict.getUuid());
							lp.setOpType(LogConstant.LOG_TYPE_DELETE);
							lp.setLogLevel(LogConstant.LOG_LEVEL_IMPORTANT);
							lp.setLogData("");
							lp.setResult(LogConstant.RESULT_SUCCESS);
							lp.save();
						}
					}
					clearTableCache(parentId);
				}
			}
		}
	}

	public static void initDictMap(List<String> dictIdList, Map<String, List<SDict>> dictMap) {
		if (dictIdList != null && dictIdList.size() > 0) {
			Iterator<String> iter = dictIdList.iterator();
			while (iter.hasNext()) {
				String uuid = iter.next();
				SDict dict = QueryDict.get(SDict.class, uuid);
				String parentId = dict.getParentId();
				List<SDict> dictList = dictMap.get(parentId);
				if (dictList == null || dictList.size() <= 0) {
					dictList = new ArrayList<SDict>();
				}
				dictList.add(dict);
				dictMap.put(parentId, dictList);
				List<SDict> children = DictMan.getDictType(uuid);
				if (children != null && children.size() > 0) {
					List<String> childIdList = new ArrayList<String>();
					Iterator<SDict> dictIter = children.iterator();
					while (dictIter.hasNext()) {
						SDict child = dictIter.next();
						childIdList.add(child.getUuid());
					}
					if (childIdList != null && childIdList.size() > 0)
						initDictMap(childIdList, dictMap);
				}
			}
		}
	}

	/**
	 * 根据表名、字典编码，通过md5加密生成字典表的uuid
	 * 
	 * @author liuzhb on Jan 13, 2014 3:39:54 PM
	 */
	public static String getUuid(String table, String dictId) {
		return Md5Util.MD5Encode(table + dictId);
	}

}
